package com.interauto.service;

import com.alibaba.fastjson.JSON;
import com.interauto.Interface.AutoAssertInterface;
import com.interauto.bean.AutoResAllBean;
import com.interauto.bean.exception.AutoAssertException;
import com.interauto.util.AutoStringUtils;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.ReadContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

/**
 * 断言校验的具体实现
 */
@Component
public class AutoAssertService implements AutoAssertInterface {
    private static final Logger logger= LoggerFactory.getLogger(AutoAssertService.class);
    @Override
    public void assertEquals(AutoResAllBean autoResAllBean) throws AutoAssertException {
        if(autoResAllBean == null || StringUtils.isEmpty(autoResAllBean.getCheckinfo())){
            throw new AutoAssertException("校验参数存在空");
        }
        logger.info("assertEquals info is ---->>>>>>>>>"+autoResAllBean.toString());
        String expectinfo=autoResAllBean.getExpectinfo();
        String checkinfo=autoResAllBean.getCheckinfo();
        String resinfo="";
        try{
            switch (autoResAllBean.getRestype()){
                case 3:
                    resinfo=String.valueOf(autoResAllBean.getObjres());
                    if(resinfo.equals(expectinfo)){
                        return;
                    }
                    break;
                case 1:
                    try{
                        ReadContext readContext=(ReadContext) autoResAllBean.getObjres();
                        Object valueinfo=readContext.read(checkinfo);
                        if(valueinfo == null){
                            throw new AutoAssertException(String.format("获取要校验的值为null;要获取的key值:%s",checkinfo));
                        }
                        resinfo= JSON.toJSON(valueinfo).toString();
                        if(resinfo.equals(expectinfo)){
                            return;
                        }
                        break;
                    }
                    catch (Exception e){
                        throw new AutoAssertException("处理json结构异常");
                    }
                default:
                    throw new AutoAssertException("响应内容结构异常");
            }
            throw new AutoAssertException(String.format("assertEquals校验不通过;期望值:%s,实际值:%s",expectinfo,resinfo));
        }
        catch (PathNotFoundException e){
            throw new AutoAssertException(String.format("响应的结果没有要校验的key值;要获取的key值:%s",checkinfo));
        }
    }

    @Override
    public void assertContains(AutoResAllBean autoResAllBean) throws AutoAssertException {
        if(autoResAllBean == null || StringUtils.isEmpty(autoResAllBean.getCheckinfo())){
            throw new AutoAssertException("校验参数存在空");
        }
        logger.info("assertContains info is ---->>>>>>>>>"+autoResAllBean.toString());
        String expectinfo=autoResAllBean.getExpectinfo();
        String checkinfo=autoResAllBean.getCheckinfo();
        String resinfo="";
        try{
            switch (autoResAllBean.getRestype()){
                case 3:
                    resinfo=String.valueOf(autoResAllBean.getObjres());
                    if(resinfo.contains(expectinfo)){
                        return;
                    }
                    break;
                case 1:
                    try{
                        ReadContext readContext=(ReadContext) autoResAllBean.getObjres();
                        Object valueinfo=readContext.read(checkinfo);
                        if(valueinfo == null){
                            throw new AutoAssertException(String.format("获取要校验的值为null;要获取的key值:%s",checkinfo));
                        }
                        resinfo= JSON.toJSON(valueinfo).toString();
                        if(resinfo.contains(expectinfo)){
                            return;
                        }
                        break;
                    }
                    catch (Exception e){
                        throw new AutoAssertException("响应JSON结构异常");
                    }
                default:
                    throw new AutoAssertException("响应内容结构异常");
            }
            throw new AutoAssertException(String.format("assertContains校验不通过;期望值:%s,实际值:%s",expectinfo,resinfo));
        }
        catch (PathNotFoundException e){
            throw new AutoAssertException(String.format("响应的结果没有要校验的key值;要获取的key值:%s",checkinfo));
        }
    }

    @Override
    public void assertHaskey(AutoResAllBean autoResAllBean) throws AutoAssertException {
        if(autoResAllBean == null || StringUtils.isEmpty(autoResAllBean.getCheckinfo())){
            throw new AutoAssertException("校验参数存在空");
        }
        logger.info("assertHaskey info is ---->>>>>>>>>"+autoResAllBean.toString());
        String checkinfo=autoResAllBean.getCheckinfo();
        try{
            if(autoResAllBean.getRestype()!=1){
                throw new AutoAssertException("assertHaskey校验失败,响应体不是json");
            }
            ReadContext readContext=(ReadContext)autoResAllBean.getObjres();
            readContext.read(checkinfo);
        }
        catch (PathNotFoundException e){
            throw new AutoAssertException(String.format("assertHaskey校验失败,响应的key不存在该值;期望值:%s",checkinfo));
        }
    }

    @Override
    public void assertEqunum(AutoResAllBean autoResAllBean) throws AutoAssertException {
        checkstrnumber(autoResAllBean,1);
    }

    @Override
    public void assertArrEqunum(AutoResAllBean autoResAllBean) throws AutoAssertException {
        checkarraynumber(autoResAllBean,1);
    }

    /**
     * 提供给数组长度校验的
     * @param checktype 1=相等，2=期望值大于实际值，3=小于
     * @throws AutoAssertException 未通过的原因
     */
    private void checkarraynumber(AutoResAllBean autoResAllBean,int checktype) throws AutoAssertException{
        if(autoResAllBean==null
                || StringUtils.isEmpty(autoResAllBean.getCheckinfo())
                || StringUtils.isEmpty(autoResAllBean.getExpectinfo())){
            throw new AutoAssertException("校验参数存在空");
        }
        logger.info("checkarraynumber info is ---->>>>>>>>>"+autoResAllBean.toString());
        String expectinfo=autoResAllBean.getExpectinfo();
        String checkinfo=autoResAllBean.getCheckinfo();
        if(!AutoStringUtils.isNumeric(expectinfo)){
            throw new AutoAssertException(String.format("期望结果值不是小数;期望结果值:%s",expectinfo));
        }
        int expectinfoint=Integer.valueOf(expectinfo).intValue();
        int jsonlistlen;
        if(autoResAllBean.getRestype()!=1){
            throw new AutoAssertException("checkarraynumber校验失败,响应体不是json");
        }
        try{
            ReadContext readContext=(ReadContext)autoResAllBean.getObjres();
            Object valueinfo=readContext.read(checkinfo);
            String jsoninfo=JSON.toJSON(valueinfo).toString();
            if(valueinfo instanceof List){
                List<Object> jsonlist=(List<Object>) valueinfo;
                jsonlistlen=jsonlist.size();
                if(checktype == 1 && expectinfoint == jsonlistlen){
                    return;
                }
                if(checktype == 2 && jsonlistlen > expectinfoint){
                    return;
                }
                if(checktype == 3 && jsonlistlen < expectinfoint){
                    return;
                }
                throw new AutoAssertException(String.format("数组长度校验失败;期望比较值:%s,实际比较值:%s",expectinfo,jsonlistlen));
            }
            throw new AutoAssertException(String.format("响应的结果不是list;响应的结果内容:%s",jsoninfo));
        }
        catch (PathNotFoundException e){
            throw new AutoAssertException(String.format("响应的结果没有要校验的key值;要获取的key值:%s",checkinfo));
        }
    }

    /**
     * 比较数字用的
     * @param checktype 1=相等，2=校验值大于期望值,3=校验值小于期望值
     */
    private void checkstrnumber(AutoResAllBean autoResAllBean,int checktype) throws AutoAssertException {
        if(autoResAllBean==null
                || StringUtils.isEmpty(autoResAllBean.getCheckinfo())
                || StringUtils.isEmpty(autoResAllBean.getExpectinfo())){
            throw new AutoAssertException("校验参数存在空");
        }
        logger.info("checkarraynumber info is ---->>>>>>>>>"+autoResAllBean.toString());
        String expectinfo=autoResAllBean.getExpectinfo();
        String checkinfo=autoResAllBean.getCheckinfo();
        if(!AutoStringUtils.isNumeric(expectinfo)){
            throw new AutoAssertException(String.format("期望结果值不是小数;期望结果值:%s",expectinfo));
        }
        if(autoResAllBean.getRestype()!=1){
            throw new AutoAssertException("checkarraynumber校验失败,响应体不是json");
        }
        try{
            ReadContext readContext=(ReadContext)autoResAllBean.getObjres();
            Object valueinfo=readContext.read(checkinfo);
            String jsoninfo= JSON.toJSON(valueinfo).toString();
            if(!AutoStringUtils.isNumeric(jsoninfo)){
                throw new AutoAssertException(String.format("实际结果值不是小数;实际结果值:%s",jsoninfo));
            }

            BigDecimal old=new BigDecimal(jsoninfo);
            BigDecimal newvalue=new BigDecimal(expectinfo);
            if(checktype == 1 && old.compareTo(newvalue) == 0){
                return;
            }
            if(checktype == 2 && old.compareTo(newvalue)>0){
                return;
            }
            if(checktype == 3 && old.compareTo(newvalue)<0){
                return;
            }
            throw new AutoAssertException(String.format("校验失败;期望值:%s,实际值:%s",expectinfo,jsoninfo));
        }
        catch (PathNotFoundException e){
            throw new AutoAssertException(String.format("响应的结果没有要校验的key值;要获取的key值:%s",checkinfo));
        }
    }


    @Override
    public void assertLsunum(AutoResAllBean autoResAllBean) throws AutoAssertException {
        checkstrnumber(autoResAllBean,3);
    }

    @Override
    public void assertGrunum(AutoResAllBean autoResAllBean) throws AutoAssertException {
        checkstrnumber(autoResAllBean,2);
    }

    @Override
    public void assertArrLsunum(AutoResAllBean autoResAllBean) throws AutoAssertException {
        checkarraynumber(autoResAllBean,3);
    }

    @Override
    public void assertArrGrunum(AutoResAllBean autoResAllBean) throws AutoAssertException {
        checkarraynumber(autoResAllBean,2);
    }

    @Override
    public void assertIsNotEmpty(AutoResAllBean autoResAllBean) throws AutoAssertException {
        if(autoResAllBean == null || StringUtils.isEmpty(autoResAllBean.getCheckinfo())){
            throw new AutoAssertException("校验参数存在空");
        }
        logger.info("assertIsNotEmpty info is ---->>>>>>>>>"+autoResAllBean.toString());
        String checkinfo=autoResAllBean.getCheckinfo();
        try{
            if(autoResAllBean.getRestype()!=1){
                throw new AutoAssertException("assertIsNotEmpty校验失败,响应体不是json");
            }
            ReadContext readContext=(ReadContext)autoResAllBean.getObjres();
            Object valueinfo=readContext.read(checkinfo);
            if(valueinfo == null){
                throw new AutoAssertException("assertIsNotEmpty校验失败,-校验内容空");
            }
            String jsoninfo=JSON.toJSON(valueinfo).toString();
            if(StringUtils.isEmpty(jsoninfo)){
                throw new AutoAssertException("assertIsNotEmpty校验失败,--校验内容空");
            }
        }
        catch (PathNotFoundException e){
            throw new AutoAssertException(String.format("assertIsNotEmpty校验失败,响应的key不存在该值;期望值:%s",checkinfo));
        }
    }
}
